package eu.vranckaert.workRegistrationWidget.util;

import android.content.Context;
import android.util.Log;
import eu.vranckaert.workRegistrationWidget.R;
import eu.vranckaert.workRegistrationWidget.domain.TimeRegistration;
import org.joda.time.*;

import java.text.DateFormat;
import java.text.DateFormatSymbols;
import java.util.*;

/**
 * @Author Dirk Vranckaert
 * Date: 24-apr-2010
 * Time: 0:41:33
 */
public final class DateUtil {
    private static final String LOG_TAG = DateUtil.class.getName();

    public static final String formatDate(Date date, Context context) {
        Locale locale = getCurrentLocale(context);
        DateFormat dateFormat = DateFormat.getDateInstance(DateFormat.SHORT, locale);
        return dateFormat.format(date);
    }

    public static final String formatTime(Date date, Context context) {
        Locale locale = getCurrentLocale(context);
        DateFormat timeFormat = DateFormat.getTimeInstance(DateFormat.SHORT, locale);
        return timeFormat.format(date);
    }

    public static final String formatDateFull(Date date, Context context) {
        Locale locale = getCurrentLocale(context);
        DateFormat dateFormat = DateFormat.getDateInstance(DateFormat.FULL, locale);

        String textDate = dateFormat.format(date);

        Calendar cal = new GregorianCalendar();
        cal.setTime(date);

        Calendar today = new GregorianCalendar();
        today.setTime(new Date());

        Calendar yesterday = new GregorianCalendar();
        yesterday.setTime(new Date());
        yesterday.add(Calendar.DATE, -1);

        if (cal.get(Calendar.YEAR) == today.get(Calendar.YEAR) &&
                cal.get(Calendar.MONTH) == today.get(Calendar.MONTH) &&
                cal.get(Calendar.DATE) == today.get(Calendar.DATE)) {
            textDate = context.getString(R.string.today) + ", " + textDate;
        } else if (cal.get(Calendar.YEAR) == yesterday.get(Calendar.YEAR) &&
                cal.get(Calendar.MONTH) == yesterday.get(Calendar.MONTH) &&
                cal.get(Calendar.DATE) == yesterday.get(Calendar.DATE)) {
            textDate = context.getString(R.string.yesterday) + ", " + textDate;
        }

        return textDate;
    }

    public static final String formatDateTimeInCurrentLocale(Date date, Context context) {
        return formatDate(date, context) + " " + formatTime(date, context);
    }

    /**
     * Checks if the first parameter is before the second parameter in time.
     * @param date1 The first date to compare.
     * @param date2 The second date to compare.
     * @return True if the first date in time is before the second, if not false.
     */
    public static boolean isBefore(Date date1, Date date2) {
        if (date1.compareTo(date2)<0) {
            return true;
        }
        return false;
    }

    /**
     * Checks if the first parameter is after the second parameter in time.
     * @param date1 The first date to compare.
     * @param date2 The second date to compare.
     * @return True if the first date in time is after the second, if not false.
     */
    public static boolean isAfter(Date date1, Date date2) {
        if (date1.compareTo(date2)>0) {
            return true;
        }
        return false;
    }

    private static Locale getCurrentLocale(Context context) {
        return context.getResources().getConfiguration().locale;
    }

    /**
     * Calculates the duration between two {@link Date} instances}.
     * @param startDate The startdate.
     * @param endDate The enddate.
     * @return The duration between the start- and enddate in hours and minutes as a String. Returns the value "ERROR"
     * if the startdate is not before the enddate.
     */
    public static String calculateDurationInTimeFormat(Date startDate, Date endDate) {
        if (startDate.compareTo(endDate) < 0) {
            int hours = calculateHoursDuration(startDate, endDate);
            int minutes = calculateMinutesDuration(startDate, endDate);

            Log.d(LOG_TAG, "Hours: " + hours);
            Log.d(LOG_TAG, "Minutes: " + minutes);

            String strMinutes = "" + minutes;
            if (minutes < 10) {
                strMinutes = "0" + strMinutes;
            }

            return hours + ":" + strMinutes;
        } else {
            return "ERROR";
        }
    }

    /**
     * Calculates the total hours and minutes worked one day.
     * @param timeRegistrations The registrations of one day.
     * @return The day total in hours and minutes (time format).
     */
    public static String calculateDayTotalsInTimeFormat(List<TimeRegistration> timeRegistrations) {
        int hours = 0;
        int minutes = 0;

        for(TimeRegistration timeRegistration : timeRegistrations) {
            Date startDate = timeRegistration.getStartDate();
            Date endDate = new Date();
            if (timeRegistration.getEndDate() != null && timeRegistration.getEndDate().getTime() > 0L) {
                endDate = timeRegistration.getEndDate();
            }

            hours += calculateHoursDuration(startDate, endDate);
            minutes += calculateMinutesDuration(startDate, endDate);

            if (minutes > 60) {
                int minutesToHours = minutes / 60;
                hours += minutesToHours;
                minutes -= (minutesToHours * 60);
            }
        }

        String strMinutes = "" + minutes;
        if (minutes < 10) {
            strMinutes = "0" + strMinutes;
        }

        return hours + ":" + strMinutes;
    }

    private static int calculateHoursDuration(Date startDate, Date endDate) {
        DateTime start = new DateTime(startDate.getTime());
        start = start.withSecondOfMinute(0);
        DateTime end = new DateTime(endDate.getTime());
        end = end.withSecondOfMinute(0);

        Hours hoursDuration = Hours.hoursBetween(start, end);
        int hours = hoursDuration.getHours();

        return hours;
    }

    public static int calculateMinutesDuration(Date startDate, Date endDate) {
        DateTime start = new DateTime(startDate.getTime());
        start = start.withSecondOfMinute(0);
        DateTime end = new DateTime(endDate.getTime());
        end = end.withSecondOfMinute(0);

        Hours hoursDuration = Hours.hoursBetween(start, end);
        Minutes minutesDuration = Minutes.minutesBetween(start, end);

        int minutes = minutesDuration.getMinutes() - hoursDuration.toStandardMinutes().getMinutes();

        return minutes;
    }
}
